#pragma once 
#include "Cond.hpp"
#include "Mutex.hpp"
#include <queue>
#include "Sem.hpp"


namespace MyRingArrayModule
{
    const int gcap = 10;
    using namespace  MySemModule;
    using namespace MyMutexModule;
    template<class T>
    class ringarray
    {
    public:
        ringarray(int cap = gcap)
            :_cap(cap),_space(cap),_data(0),_data_step(0),_space_step(0)
        {
            _rq.resize(_cap,0);
        }
        void Enque(T&data){
            //生产者
            _space.P();
            {
                LockGuard lock(_product);
                cout << "生产者开始生产" << endl;
                _rq[_space_step] = data;
                _space_step = (_space_step + 1) % _cap;
                cout << "生产这生产完毕" << endl;
            }
            _data.V();
        }
        void Pop(T* data){
            //消费者
            _data.P(); //数据减少
            {
                LockGuard lock(_consume);
                cout << "消费者开始消费" << endl;
                *data = _rq[_data_step];
                _data_step = (_data_step + 1) % _cap;
                cout << "消费者消费OK" << endl;
            }
            _space.V();
        }
        ~ringarray(){}
    private:
        int _cap;
        Sem _space;
        Sem _data;
        Mutex _product;
        Mutex _consume;
        int _data_step;
        int _space_step;
        vector<T> _rq;
    };
};